////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
//  File name:   PickObjectTool.h
//  Version:     v1.00
//  Created:     18/12/2001 by Timur.
//  Compilers:   Visual C++ 6.0
//  Description: Definition of PickObjectTool, tool used to pick objects.
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#ifndef __MaterialPickTool_h__
#define __MaterialPickTool_h__

#if _MSC_VER > 1000
#pragma once
#endif

//////////////////////////////////////////////////////////////////////////
class CMaterialPickTool : public CEditTool
{
public:
	DECLARE_DYNCREATE(CMaterialPickTool)

	CMaterialPickTool();

	static void RegisterTool( CRegistrationContext &rc );

	//////////////////////////////////////////////////////////////////////////
	// CEditTool implementation
	//////////////////////////////////////////////////////////////////////////
	virtual bool MouseCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
	virtual void Display( DisplayContext &dc );
	//////////////////////////////////////////////////////////////////////////

protected:

	enum EMaterialPickingObjType
	{
		eMPT_StaticObj,
		eMPT_Vegetation,
		eMPT_Terrain,
		eMPT_Entity,
		eMPT_Max
	};

	bool OnMouseMove( CViewport *view,UINT nFlags,CPoint point );
	void SetMaterial( IMaterial *pMaterial,int nSubMtlId=-1 );

	void FindNearestMatFromGeneralObjects( 
		const Vec3& vWorldRaySrc, 
		const Vec3& vWorldRayDir, 
		CViewport *view,
		IMaterial*& pOutLastMaterial, 
		SRayHitInfo& outHitInfo, 
		EMaterialPickingObjType& outObjType );

	void FindNearestMatFromSolids( 
		const Vec3& vWorldRaySrc, 
		const Vec3& vWorldRayDir, 
		CViewport *view,
		IMaterial*& pOutLastMaterial, 
		SRayHitInfo& outHitInfo, 
		EMaterialPickingObjType& outObjType );

	void FindNearestMatFromDecals( 
		const Vec3& vWorldRaySrc, 
		const Vec3& vWorldRayDir, 
		CViewport *view,
		IMaterial*& pOutLastMaterial, 
		SRayHitInfo& outHitInfo, 
		EMaterialPickingObjType& outObjType );

	void FindNearestMatFromVegetations(		
		const Vec3& vWorldRaySrc, 
		const Vec3& vWorldRayDir, 
		IMaterial*& pOutLastMaterial, 
		SRayHitInfo& outHitInfo, 
		EMaterialPickingObjType& outObjType );

	void FindNearestMatFromEntities( 
		const Vec3& vWorldRaySrc, 
		const Vec3& vWorldRayDir, 
		CViewport *view,		
		IMaterial*& pOutLastMaterial, 
		SRayHitInfo& outHitInfo, 
		EMaterialPickingObjType& outObjType );

	void FindNearestMatFromTerrain( 
		const Vec3& vWorldRaySrc, 
		const Vec3& vWorldRayDir, 
		IMaterial*& pOutLastMaterial, 
		SRayHitInfo& outHitInfo, 
		EMaterialPickingObjType& outObjType );

	bool RayIntersection( 
		const Vec3& vWorldRaySrc, 
		const Vec3& vWorldRayDir, 
		IRenderNode* pRenderNode,
		IEntity* pEntity,
		IStatObj* pStatObj, 
		const Matrix34A& WorldTM, 
		SRayHitInfo& outHitInfo,
		IMaterial** ppOutLastMaterial );

	bool RayIntersection( 
		const Vec3& vWorldRaySrc, 
		const Vec3& vWorldRayDir, 
		IStatObj* pStatObj, 
		IMaterial** ppOutLastMaterial, 
		const Matrix34A& WorldTM, 
		SRayHitInfo& outHitInfo );

	bool RayIntersection( 
		const Vec3& vWorldRaySrc, 
		const Vec3& vWorldRayDir,
		IRenderNode* pRenderNode,
		IMaterial** ppOutLastMaterial, 
		const Matrix34A& WorldTM, 
		SRayHitInfo& outHitInfo );	

	bool RayIntersection(
		const Vec3& vWorldRaySrc,
		const Vec3& vWorldRayDir,
		IEntity* pEntity,
		IMaterial** ppOutLastMaterial, 
		const Matrix34A& WorldTM,
		SRayHitInfo& outHitInfo );

	bool RayIntersection( 
		const Vec3& vWorldRaySrc, 
		const Vec3& vWorldRayDir, 
		CBaseObject* pBaseObject,
		IMaterial** ppOutLastMaterial, 
		SRayHitInfo& outHitInfo );

	bool RayWorldToLocal( 
		const Matrix34A& WorldTM, 
		const Vec3& vWorldRaySrc, 
		const Vec3& vWorldRayDir, 
		Vec3& outRaySrc, 
		Vec3& outRayDir );

	virtual ~CMaterialPickTool();
	// Delete itself.
	void DeleteThis() { delete this; };

	static void AssignObjectMaterial( CBaseObject* pObject, const SRayHitInfo& outHitInfo, IMaterial** pOutMaterial );
	bool IsMaterialValid( CMaterial* pMateral ) const;

	int m_surfaceId;
	_smart_ptr<IMaterial> m_pMaterial;
	_smart_ptr<IMaterial> m_pMaterialForDisplay;
	CString m_displayString;
	Vec3 m_hitNormal;
	Vec3 m_hitPos;
	CPoint m_Mouse2DPosition;

	CMaterialHighlightData materialHighlightData;
};


#endif // __MaterialPickTool_h__
